""" Code to test and explore the gdata api and its quirks """

import getpass
import gdata.docs.data
import gdata.docs.client
import gdata.docs.service
import tempfile
import os
import urllib

# Set to your own test account
#TEST_ACCOUNT = 'my_test_account@gmail.com'

def MakeHackUri(entry):
  """ Something is busted.... """
  hack_uri = '/feeds/default/private/full/' + entry.resource_id.text
  hack_uri = hack_uri.replace(':', '%3A')
  return hack_uri

def PrintFeed(feed):
  print ''
  if not feed.entry:
    print 'No entries in feed.'
  for entry in feed.entry:
    print entry.title.text.encode('UTF-8'), entry.GetDocumentType() 
    print 'resource_id:  ', entry.resource_id.text,
    print 'content: ', entry.content.src
  print ''

client = gdata.docs.client.DocsClient(source='gdfs')
client.ssl = True  # Force all API requests through HTTPS
client.http_client.debug = False # Set to True for debugging HTTP requests
try:
  token_string = open('/tmp/gdfs_token').read()
  client.auth_token = gdata.gauth.token_from_blob(token_string)
except:
  token = client.RequestClientLoginToken(TEST_ACCOUNT,
                                         getpass.getpass(),
                                         client.source);
  client.auth_token = token
  open('/tmp/gdfs_token', 'w').write(gdata.gauth.token_to_blob(token))

feed_uri = '/feeds/default/private/full/folder%3Aroot/contents'
feed = client.GetDocList(feed_uri)
PrintFeed(feed)

print 'TEST that the account is empty'
# Get ALL files and folders
feed_uri = '/feeds/default/private/full?showfolders=true'
feed = client.GetDocList(feed_uri)
if feed.entry:
  resp = raw_input('Root is not empty, delete everything? [Y,n] ')
  if resp != 'n':
    # Try to delete everything
    print 'Deleting everything'
    for entry in feed.entry:
      print '  Deleting', entry.title.text.encode('UTF-8')
      client.Delete(entry.GetEditLink().href + '?delete=true', force=True)
  else:
    raise Exception('Account was not empty')
  feed = client.GetDocList(feed_uri)
  if feed.entry:
    raise Exception('Failed to empty account')
print '  PASSED'

NUM = 5  # Minimum of 2
folders = []
files = []

print 'TEST create folders'
for i in range(NUM):
  folders.append(client.Create('folder', 'folder_%d' % i))
print '  PASSED'

print 'TEST check folders'
feed_uri = '/feeds/default/private/full/folder%3Aroot/contents'
feed = client.GetDocList(feed_uri)
if len(feed.entry) != NUM:
  raise Exception('There are not NUM folders in the root')
print '  PASSED'

print 'TEST create sub-folders in folder_0'
for i in range(NUM):
  folders.append(client.Create('folder', 'folder_%d' % i, folders[0]))

feed = client.GetDocList(folders[0].content.src)
if len(feed.entry) != NUM:
  raise Exception('There are not NUM sub-folders in folder_0')
print '  PASSED'

print 'TEST folder rename'
for i in range(NUM):
  entry = folders[i]
  entry.title.text = entry.title.text + '_renamed'
  folders[i] = client.Update(entry)
print '  PASSED'

# MOVE IS BROKEN, SOMEHOW THE MOVED THING ENDS UP ALSO IN THE ROOT FOLDER!
print 'TEST sub-folder move to folder_1'
for i in range(NUM, len(folders)):
  ## Almost good: leaves a copy in root
  #folders[i] = client.Move(folders[i], folders[1])
  ## Almost good:  leaves a copy in source folder
  #folders[i] = client.Move(folders[i], folders[1], keep_in_folders=True)
  # HACK: Moves to new folder, and then removes source folder!
  folders[i] = client.Move(folders[i], folders[1], keep_in_folders=True)
  client.Delete(folders[i], force=True)
print '  PASSED'

print 'TEST create files in last subdir'
f, tmp_path = tempfile.mkstemp()
os.close(f)
for i in range(NUM):
  files.append(client.Upload(tmp_path, 'file_%d'%i,
        folder_or_uri=folders[-1],
        content_type='application/pdf'))
print '  PASSED'

print 'TEST check files in last subdir'
feed = client.GetDocList(folders[-1].content.src)
if len(feed.entry) != NUM:
  raise Exception('There are not NUM files in last subfolder')
print '  PASSED'

print 'TEST create files in penultimate subdir'
f, tmp_path = tempfile.mkstemp()
os.close(f)
for i in range(NUM):
  files.append(client.Upload(tmp_path, 'file_%d'%i,
        folder_or_uri=folders[-2],
        content_type='application/pdf'))
print '  PASSED'

print 'TEST check files in penultimate subdir'
feed = client.GetDocList(folders[-2].content.src)
if len(feed.entry) != NUM:
  raise Exception('There are not NUM files in penultimate subfolder')
print '  PASSED'

print 'TEST get each file entry'
for i in range(NUM):
  feed_uri = folders[-1].content.src + '?title=' + 'file_%d' %i
  feed = client.GetDocList(feed_uri)
  if len(feed.entry) != 1:
    raise Exception('More than one entry')
print '  PASSED'

print 'TEST get each file entry in wrong folder'
for i in range(NUM):
  feed_uri = folders[1].content.src + '?title=' + 'file_%d' %i
  feed = client.GetDocList(feed_uri)
  if len(feed.entry) != 0:
    raise Exception('Found feed entry when there should be zero')
print '  PASSED'

print 'TEST inplace file rename'
for i in range(NUM):
  entry = files[i]
  entry.title.text = entry.title.text + '_renamed'
  files[i] = client.Update(entry)
print '  PASSED'

print 'TEST move from penultimate folder to last folder'
for i in range(NUM, len(files)):
  files[i] = client.Move(files[i], folders[-1])
print '  PASSED'

print 'TEST delete files HACKED URI'
for entry in files:
  print '  Deleting', entry.title.text.encode('UTF-8')
  response = client.Delete(MakeHackUri(entry) + '?delete=true', force=True)
  if (response.reason != 'OK'):
    raise Exception('Could not delete ' + entry.content.src)
print '  PASSED'

## THIS DOESN"T WORK -- IT REMOVES THE FILES FROM THE SUBDIR, BUT THEY ARE STILL PRESENT IN THE ROOT!?!
#print 'TEST delete files'
#for entry in files:
#  print '  Deleting', entry.title.text.encode('UTF-8')
#  response = client.Delete(entry.GetEditLink().href + '?delete=true',
#                           force=True)
#  if (response.reason != 'OK'):
#    raise Exception('Could not delete ' + entry.content.src)
#print '  PASSED'

print 'TEST check files deleted in last subdir'
feed = client.GetDocList(folders[-1].content.src)
if feed.entry:
  raise Exception('Did not delete files in last subfolder')
print '  PASSED'

print 'TEST check files deleted in penultimate subdir'
feed = client.GetDocList(folders[-2].content.src)
if feed.entry:
  raise Exception('Did not delete files in penultimate subfolder')
print '  PASSED'

print 'TEST delete folders'
for entry in reversed(folders):
  print '  Deleting', entry.title.text.encode('UTF-8')
  response = client.Delete(MakeHackUri(entry) + '?delete=true', force=True)
  if (response.reason != 'OK'):
    raise Exception('Could not delete ' + entry.content.src)
print '  PASSED'

## THIS DOESN"T WORK -- IT REMOVES THE FILES FROM THE SUBDIR, BUT THEY ARE STILL PRESENT IN THE ROOT!?!
#print 'TEST delete folders'
#for entry in reversed(folders):
#  print '  Deleting', entry.title.text.encode('UTF-8')
#  response = client.Delete(entry.GetEditLink().href + '?delete=true',
#                           force=True)
#  if (response.reason != 'OK'):
#    raise Exception('Could not delete ' + entry.content.src)
#print '  PASSED'
